package com.example.fengyungo_user.fragment;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.LocationSource;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.example.fengyungo_user.R;
import com.example.fengyungo_user.activity.main.EndActivity;
import com.example.fengyungo_user.constant.MapConstant;
import com.example.fengyungo_user.utils.MapUtils;

public class MainFragment extends Fragment implements AMapLocationListener, LocationSource {

    private static final String TAG = "MainFragment";

    /**
     * 地图
     */
    private MapView mapView;
    /**
     * 声明AMapLocationClient类对象
     */
    private AMapLocationClient mLocationClient = null;
    /**
     * 地图控制器
     */
    private AMap aMap = null;
    /**
     * 位置更改监听
     */
    private OnLocationChangedListener mListener;
    /**
     * 当前地址
     */
    private String address;
    /**
     * 起点
     */
    private TextView beginTextView;
    /**
     * 终点
     */
    private TextView endTextView;
    /**
     * 起点
     */
    private LatLonPoint beginLatLonPoint;
    /**
     * 当前地址
     */
    private String currentPosition;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);

        beginTextView = view.findViewById(R.id.tv_begin);
        endTextView = view.findViewById(R.id.tv_end);

        // 跳转到设置终点页面
        endTextView.setOnClickListener((v) -> {
            Log.d(TAG, "onCreateView: beginLatLonPoint=" + beginLatLonPoint);
            Intent intent = new Intent(getActivity(), EndActivity.class);
            intent.putExtra(MapConstant.BEGIN_LAT, beginLatLonPoint.getLatitude());
            intent.putExtra(MapConstant.BEGIN_LON, beginLatLonPoint.getLongitude());
            intent.putExtra(MapConstant.BEGIN_ADDRESS, currentPosition);
            startActivity(intent);
        });

        // TODO: 2024/2/2 隐私政策

        // 初始化定位
        mLocationClient = MapUtils.initLocation(getActivity(), this);
        // 初始化地图
        initMap(view, savedInstanceState);
        // 检查Android版本
        checkingAndroidVersion();

        return view;
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mapView != null) {
            mapView.onSaveInstanceState(outState);
        }
    }

    /**
     * 方法必须重写
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        //销毁定位客户端，同时销毁本地定位服务。
        if (mLocationClient != null) {
            mLocationClient.onDestroy();
        }
    }

    /**
     * 初始化地图
     *
     * @param view               View
     * @param savedInstanceState Bundle
     */
    private void initMap(View view, Bundle savedInstanceState) {
        mapView = view.findViewById(R.id.map);
        //创建地图
        mapView.onCreate(savedInstanceState);
        //初始化地图控制器对象
        aMap = mapView.getMap();

        MapUtils.setLocationStyle(aMap);

        MapUtils.setMap(aMap);

        // 设置定位监听
        aMap.setLocationSource(this);
        // 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.setMyLocationEnabled(true);

        aMap.setOnMapLoadedListener(() -> {
            MapUtils.addCenterMarker(aMap);
            Log.d(TAG, "onMapLoaded: aMap=" + aMap);
        });
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                //开始获取中心点的marker坐标
                try {
                    beginLatLonPoint = new LatLonPoint(cameraPosition.target.latitude,
                            cameraPosition.target.longitude);
                    startFindPointNameQuery(beginLatLonPoint, beginTextView, getActivity());
                    Log.d(TAG, "onCameraChangeFinish: beginLatLonPoint=" + beginLatLonPoint);
                } catch (AMapException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void startFindPointNameQuery(final LatLonPoint point, TextView selectedPosition, Context context) throws AMapException {
        //创建一个GeocodeSearch  逆地理编码和地理编码类
        GeocodeSearch search = new GeocodeSearch(context);
        //设置监听器
        search.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                //逆地理编码异步返回
                //由于我们的版本是大于3.2.1 所以成功是1000
                if (i == MapConstant.RESULT_SUCCESS) {
                    //RegeocodeAddress是逆地理编码搜索的地理结果。
                    RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
                    Log.d(TAG, "onRegeocodeSearched: regeocodeAddress=" + regeocodeAddress);
                    //逆地理编码返回的格式化地址。
                    currentPosition = regeocodeAddress.getFormatAddress();
                    // 显示当前地址
                    selectedPosition.setText(currentPosition);
                } else {
                    selectedPosition.setText(MapConstant.GET_POSITION_FAILED);
                }

            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                //地理编码异步返回
            }
        });
        //point - 要进行逆地理编码的地理坐标点。
        //radius - 查找范围。默认值为1000，取值范围1-3000，单位米。
        //latLonType - 输入参数坐标类型。包含GPS坐标和高德坐标。 GeocodeSearch.AMAP 、GeocodeSearch.GPS
        float radius = 1000F;
        //逆地理RegeocodeQuery构造函数
        RegeocodeQuery regeocodeQuery = new RegeocodeQuery(point, radius, GeocodeSearch.AMAP);
        //发起逆地理编码异步查询
        search.getFromLocationAsyn(regeocodeQuery);
    }

    /**
     * 检查Android版本
     */
    private void checkingAndroidVersion() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //Android6.0及以上先获取权限再定位
            getPermission();
            mLocationClient.startLocation();
        } else {
            //Android6.0以下直接定位
            mLocationClient.startLocation();
        }
    }

    /**
     * 获取权限
     */
    private void getPermission() {
        // 动态获取权限
        try {
            //需要的权限
            String[] permArr = {
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            };
            boolean needReq = false;
            for (String s : permArr) {
                if (ContextCompat.checkSelfPermission(getActivity(), s) != PackageManager.PERMISSION_GRANTED) {
                    needReq = true;
                    break;
                }
            }
            if (needReq) {
                ActivityCompat.requestPermissions(getActivity(), permArr, 1);
            }
        } catch (Exception e) {
            Toast.makeText(getActivity(), getString(R.string.get_permission_error), Toast.LENGTH_SHORT).show();
            Log.d(TAG, "checkVersion: e:" + e);
        }
    }

    /**
     * 接收异步返回的定位结果
     *
     * @param aMapLocation AMapLocation
     */
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null) {
            if (aMapLocation.getErrorCode() == 0) {
                //地址
                address = aMapLocation.getAddress();
                // 显示起点
                beginTextView.setText(address);
                Log.d(TAG, "onLocationChanged: address=" + address);
                // 停止定位后，本地定位服务并不会被销毁
                mLocationClient.stopLocation();

                // 显示地图定位结果
                if (mListener != null) {
                    // 显示系统图标
                    mListener.onLocationChanged(aMapLocation);
                }
            } else {
                //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                Log.e(TAG, "AmapError location Error, ErrCode:"
                        + aMapLocation.getErrorCode() + ", errInfo:"
                        + aMapLocation.getErrorInfo());
            }
        }
    }

    /**
     * 激活定位
     *
     * @param onLocationChangedListener OnLocationChangedListener
     */
    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mLocationClient != null) {
            // 启动定位
            mLocationClient.startLocation();
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }
}
